/**
 * 安卓白金英雄坛制作组 <br>
 * 文件名：MainChar.java <br>
 * 创建时间：2013-7-26 上午9:49:38 <br>
 * 所属项目：GmudEX <br>
 * @author 12548 <br>
 */
package lostland.gmud.exv2.data;

import android.util.SparseIntArray;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

import lostland.gmud.exv2.Assets;
import lostland.gmud.exv2.Game;
import lostland.gmud.exv2.GameConstants;
import lostland.gmud.exv2.Gmud;
import lostland.gmud.exv2.blgframework.impl.BLGGraphics;
import lostland.gmud.exv2.blgframework.impl.BLGPixmap;

/**
 * 类名：MainChar <br>
 * 说明：辣过主角……
 *
 * @author 12548
 */
public class MainChar extends Npc implements Serializable {

	private static final long serialVersionUID = 124839611434801433L;

	/* （非 Javadoc）
	 * @see lostland.gmud.exv2.data.Npc#getMaxhp()
	 */
	@Override
	public int getMaxhpInTheory() {
		int t = super.getMaxhpInTheory();
		if (Game.getData().spouse != null) {
			t *= 0.8;
		}
		return t;
	}


	public int day = 0;
	public int month = 0;

	public int food;
	public int drink;

	public int looking = 30; //相貌
	public int lookingplus = 0; //相貌修正值

	public int potential = 0; //潜能

	public int learning[];  //学习进度

	private static final int INVENTORY_SIZE = 40;
	public SparseIntArray inventory_pile = new SparseIntArray(); // 拥有物品数量

	public Integer get_pile(Item itm) {
		int x = inventory.indexOf(itm);
		if (x < 0) return 0;
		if (itm.getTemplate().getPile() > 1)
			return inventory_pile.get(x);
		else {
			int cnt = 0;
			for (Item i : inventory)
				if (itm.equals(i)) {
					cnt++;
				}
			return cnt;
		}
	}


	public int masterid = -1; // 师父ID

	public int luckness = 50; // 幸运

	public void drop(int itmid, int count) {
		Item itm = findItem(itmid);
		if (Item.notNull(itm)) {
			drop(itm, count);
		}
	}


	public boolean drop(Item item) {
		if (!item.canDrop())
			return false;
		if (inventory.indexOf(item) < 0)
			return false;
		if (item.getTemplate().getPile() > 1) {
			inventory_pile.put(inventory.indexOf(item), Math.max(0, get_pile(item) - 1));
			refreshItems();
		} else {
			int p = inventory.indexOf(item);
			SparseIntArray sia = new SparseIntArray();
			for (int j = 0; j < inventory_pile.size(); j++) {
				if (inventory_pile.keyAt(j) > p) {
					sia.put(inventory_pile.keyAt(j) - 1, inventory_pile.valueAt(j));
				} else if (inventory_pile.keyAt(j) < p) {
					sia.put(inventory_pile.keyAt(j), inventory_pile.valueAt(j));
				}
			}
			inventory_pile = sia;
			inventory.remove(p);
		}
		return true;
	}

	public void drop(Item item, int count) {

		if (count < 0) {
			//noinspection StatementWithEmptyBody
			while(drop(item)) {
			}
		} else {
			for (int i = 0; i < count; i++) {
				drop(item);
			}
		}

	}

	/**
	 * 是否仅有这一个物品，不算正在使用的
	 *
	 * @param item 目标物品
	 * @return 若该物品无法丢弃，返回true
	 */
	public boolean only(Item item) {
		if (!item.canDrop())
			return true;
		boolean flag1 = false;
		int flag2 = 0;
		for (Item i : equipments) {
			if (item.equals(i)) {
				flag1 = true;
			}
		}
		for (Item i : inventory) {
			if (i.equals(item)) {
				flag2++;
			}
		}

		return flag1 && flag2 <= 1;
	}

	public boolean notOnly(int itmid) {
		Item findItem = findItem(itmid);
		return !Item.notNull(findItem) || !only(findItem);
	}

	/**
	 * 刷新物品
	 */
	public void refreshItems() {
		boolean flag = false;

		do {
			flag = false;

			for (int i = 0; i < inventory_pile.size(); i++) {
				if (inventory_pile.valueAt(i) <= 0) {
					flag = true;
					SparseIntArray sia = new SparseIntArray();
					for (int j = 0; j < inventory_pile.size(); j++) {
						if (i == j) {
							continue;
						}

						if (inventory_pile.keyAt(j) > inventory_pile.keyAt(i)) {
							sia.put(inventory_pile.keyAt(j) - 1, inventory_pile.valueAt(j));
						} else {
							sia.put(inventory_pile.keyAt(j), inventory_pile.valueAt(j));
						}
					}
					inventory.remove(inventory_pile.keyAt(i));
					inventory_pile = sia;
				}

				if(flag) {
					break;
				}
			}
		} while (flag);


		//确保物品栏与装备的是同一个实例
		for (Item i : equipments)
			if (Item.notNull(i)) {
				flag = true;
				for (Item j : inventory) {
					if (j == i) {
						flag = false;
					}
				}

				if (flag) {
					for (int j = 0; j < inventory.size(); j++) {
						if (inventory.get(j).equals(i)) {
							inventory.set(j, i);
							break;
						}
					}
				}
			}
	}

	/**
	 * 获得物品
	 *
	 * @param item 物品
	 * @return 如果物品栏已满或堆叠已满则失败返回false，成功返回true
	 */
	@Override
	public boolean give(Item item) {
		if (!(have(item) && item.getTemplate().getPile() > 1)) {
			if (inventory.size() >= getInventorySize()) return false;
			inventory.add(item);
		}

		if (item.getTemplate().getPile() > 1) {
			if (get_pile(item) >= item.getTemplate().getPile()) return false;
			inventory_pile.put(inventory.lastIndexOf(item), get_pile(item) + 1);
		}
		return true;
	}

	/**
	 * 强制获得物品，即使物品栏已满
	 *
	 * @param item 物品
	 */
	public void force_give(Item item) {
		if (!(have(item) && item.getTemplate().getPile() > 1)) {
			inventory.add(item);
		}

		if (item.getTemplate().getPile() > 1) {
			inventory_pile.put(inventory.lastIndexOf(item), get_pile(item) + 1);
		}
	}

	/**
	 * 强制获得物品，即使物品栏已满
	 *
	 * @param itmid 物品模板ID
	 */
	public void force_give(int itmid) {
		force_give(Item.generateItem(itmid, -1));
	}

	public HashMap<String, Item> getItemList2Show() {
		HashMap<String, Item> t = new HashMap<>();
		for (Item i : inventory) {
			String s = i.getName();
			int x = get_pile(i);
			if (x > 1) {
				s += "x " + x;
			}
			t.put(s, i);
		}
		return t;
	}

	public int getFoodmax() {
		return 75 + str * 15;
	}

	public int getWatermax() {
		return 50 + str * 15;
	}

	/**
	 * 获得相貌值
	 *
	 *  由先天相貌+驻颜术+相貌修正决定<br>
	 *  驻颜术每10级增加一点相貌值，在相貌值小于10时每5级增加一点
	 */
	public int getface() {
		int f = looking + skills[10] / 10;
		if (f < 10) {
			f += skills[10] / 10;
		}
		return f + lookingplus;
	}

	/**
	 * 是否处于饥渴状态
	 */
	public boolean isHungry() {
		return food <= 0 || drink <= 0;
	}

	public MainChar() {
		super();
		fame = 128;
//		setSp(100);
//		setHp(100);
//		setMaxhp(100);
		setFp(0);
		maxfp = 0;
		ads = 0;
		gold = 100;
		id = -1;

		learning = new int[100];
		Arrays.fill(learning, 0);

		inventory = new ArrayList<>();

		skillsckd = new int[]{-1, -1, -1, -1, -1};
	}

	/**
	 * 没有获得全部武器（30把）
	 */
	public boolean hbno_all_weapons() {
		for (ItemTemplate i : Gmud.getWp()) {
			if (i.getKind() == 2 && (!hbno(i.getId())) && i.getId() < 82)
				return false;
		}

		return true;
	}

	public boolean hbno(int i) {
		return have(i) && (notOnly(i));
	}

	public void drop_all_weapons() {
		for (ItemTemplate i : Gmud.getWp()) {
			if (i.getKind() == 2 && have(i.getId())) {
				drop(i.getId(), 1);
			}
		}
	}

	/**
	 * 获得全部30武器（测试用）
	 */
	public void give_all_weapons() {
		for (ItemTemplate i : Gmud.getWp()) {
			if (i.getId() > 0 && i.getKind() == 2) {
				give(i.getId());
			}
		}
	}

	/**
	 * 获取合法声望
	 */
	public int getFame() {
		return Gmud.format(fame, 0, 160);
	}

	/**
	 * 获取合法福缘
	 */
	public int getFate() {
		return Gmud.format(fame, 0, 20);
	}

	/**
	 * @param potential 要设置的潜能
	 */
	public void setPotential(int potential) {
		this.potential = potential;
	}

	/**
	 * @param delta 挣钱或损失钱
	 */
	public void earnMoney(int delta) {
		gold += delta;
		gold = Math.max(0, gold); //不能为负
	}


	/* （非 Javadoc）
	 * @see lostland.gmud.exv2.data.Npc#draw(int, int, int, int)
	 */
	@Override
	public void drawInMap(int x, int y, int dx, int dy) {
		BLGPixmap pixmap = (BLGPixmap) Assets.getMainchar();
		if (sex > 0) {
			pixmap = (BLGPixmap) Assets.getGirl();
		}
		((BLGGraphics) Game.getInstance().getGraphics()).drawPixmapInMap(pixmap, x * 32 + dx, (y + 1) * 32 - 48 + dy
				, 0, 0, 32, 48);
	}


	/**
	 * 获取物品栏格数。
	 */
	public int getInventorySize() {
		int inventorySize = INVENTORY_SIZE;
		if (haveTalent(2057)) {
			inventorySize -= 10;
		}
		for (Item i : inventory) {
			if (!i.canDrop()) {
				inventorySize++;
			}
		}
		return inventorySize;
	}


	/* （非 Javadoc）
	 * @see lostland.gmud.exv2.data.Npc#getFp()
	 */
	@Override
	public int getFp() {
		if (fp > GameConstants.FP_LIMIT * 2) {
			fp = GameConstants.FP_LIMIT * 2;
		}
		return fp;
	}


	/* （非 Javadoc）
	 * @see lostland.gmud.exv2.data.Npc#setFp(int)
	 */
	@Override
	public void setFp(int fp) {
		super.setFp(fp);
		if (fp > GameConstants.FP_LIMIT * 2) {
			fp = GameConstants.FP_LIMIT * 2;
		}
	}


	public boolean checkLimit(int llvl) {

		final int[] LIMIT_ITEM_ENCHANT_LVL = {30, 30, 25, 25, 20, 20, 15, 10};

		for (Item itm : equipments) {
			if (itm.ex_level > LIMIT_ITEM_ENCHANT_LVL[llvl])
				return false;
			if (itm.runes.size() > (LIMIT_ITEM_ENCHANT_LVL[llvl] - 1) / 3)
				return false;
		}

		for (Item itm : inventory) {
			if (itm.ex_level > LIMIT_ITEM_ENCHANT_LVL[llvl])
				return false;
			if (itm.runes.size() > (LIMIT_ITEM_ENCHANT_LVL[llvl] - 1) / 3)
				return false;
		}

		final int[] LIMIT_SP = {99999, 9999, 8000, 7000, 6000, 5000, 4000, 3000};
		final int[] LIMIT_FP = {99999, 20000, 18000, 14000, 10000, 6000, 4000, 3000};
		final int[] LIMIT_EXP = {999999999, 99999999, 8000000, 7000000, 6000000, 5000000, 4000000, 3000000};
		final int[] LIMIT_SKLLV = {99999, 9999, 5000, 4000, 3000, 2000, 1000, 500};

		if(getSp() > LIMIT_SP[llvl])
			return false;

		if (fp > LIMIT_FP[llvl])
			return false;

		if (exp > LIMIT_EXP[llvl])
			return false;

		int sum = 0;
		for (int i : skills) {
			sum += i;
		}

		if (sum > LIMIT_SKLLV[llvl])
			return false;


		final int[] LIMIT_ATTR = {120, 115, 110, 105, 100, 100, 100, 100};

		int attr_sum = str + bon + agi + wxg + atk + def + hit + evd;
		return attr_sum <= LIMIT_ATTR[llvl];


	}


	public boolean have(int itmid, int count) {
		return get_pile(findItem(itmid)) >= count;
	}
}
